﻿using log4net;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using QiAdmin.Core;
using QiAdmin.Core.Models;
using QiAdmin.Core.Services.Token;
using QiAdmin.Core.Utils.Request;
using QiAdmin.Entity;
using QiAdmin.Model.Dtos.Input;
using QiAdmin.Service.IService;

namespace QiAdmin.WebApi.MiddleWares
{
    public class WebApiLog
    {
        readonly RequestDelegate _next;
        readonly IServiceScopeFactory _serviceScopeFactory;
        public WebApiLog(RequestDelegate next, IServiceScopeFactory serviceScopeFactory)
        {
            _next = next;
            _serviceScopeFactory = serviceScopeFactory;
        }
        public async Task InvokeAsync(HttpContext context)
        {
            if (!App.AppSettings.System.IgnoreWebApiLogPaths.ToList().Exists(s => context.Request.Path.ToString().Contains(s)))
            {
                TSysWebapiLog_IN sysWebapiLog = new TSysWebapiLog_IN();
                sysWebapiLog.IP = RequestInfoUtil.GetIp(context);
                sysWebapiLog.Path = context.Request.Path.ToString();

                using var scope = _serviceScopeFactory.CreateScope();
                var tokenService = scope.ServiceProvider.GetRequiredService<ITokenService>();
                TokenData tokenData = tokenService.ParseToken(context);
                if (tokenData != null)
                {
                    sysWebapiLog.DeptId = tokenData.UserDept;
                    sysWebapiLog.UserId = tokenData.UserId;
                }

                #region 传入参数解析
                StringBuilder inarg = new StringBuilder();
                if (context.Request.HasFormContentType)
                {
                    foreach (var item in context.Request.Form)
                    {
                        inarg.AppendLine(item.Key + ":" + item.Value);
                    }
                }
                else if (context.Request.Query.Count > 0)
                {
                    foreach (var item in context.Request.Query)
                    {
                        inarg.AppendLine(item.Key + ":" + item.Value);
                    }
                }
                else
                {
                    context.Request.EnableBuffering();
                    StreamReader streamReader = new StreamReader(context.Request.Body);
                    inarg.AppendLine(await streamReader.ReadToEndAsync());
                    context.Request.Body.Seek(0, SeekOrigin.Begin);
                }
                string input = inarg.ToString();
                sysWebapiLog.InTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                sysWebapiLog.Input = input.Replace("\r\n", "").Trim();
                #endregion

                #region 传出参数解析
                var originalBodyStream = context.Response.Body;
                string output = string.Empty;
                using (var responseBody = new MemoryStream())
                {
                    context.Response.Body = responseBody;
                    await _next(context);
                    output = await GetResponse(context.Response);
                    await responseBody.CopyToAsync(originalBodyStream);
                }
                sysWebapiLog.OutTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
                sysWebapiLog.Output = output.Replace("\r\n", "").Trim();
                #endregion

                var sysWebapiLogService = scope.ServiceProvider.GetRequiredService<ITSysWebapiLogService>();
                try { await sysWebapiLogService.AddAsync(sysWebapiLog); } catch { }
            }
            else
            {
                await _next(context);
            }
        }
        public async Task<string> GetResponse(HttpResponse response)
        {
            response.Body.Seek(0, SeekOrigin.Begin);
            var text = await new StreamReader(response.Body).ReadToEndAsync();
            response.Body.Seek(0, SeekOrigin.Begin);
            return text;
        }
    }
}
